#!/usr/bin/perl
#
# 服务器连通性监控脚本
#

use IO::Socket;
use IO::File;
use MIME::Base64;
use LWP::Simple;
use Net::SMTP_auth;
use Net::SMTP::SSL;

##############################
# Constant define (configure)
##############################
# sms config
#use constant SMS_INFO 		=> "http://wa.moxiu.com/co/moniter.php";
#use constant SMS_INFO 		=> "http://219.232.239.116/cacti/moniter/moniter.php";
use constant SMS_INFO 		=> "http://cacti.web.moxiu.com/moniter/moniter.php";
# mail config
use constant MAIL_ADDR          => ('to'=>'ycg@moxiu.net,15911100337@139.com', 'from'=>'kedy211@163.com');
use constant SMTP_INFO          => ('host'=>'smtp.163.com', 'port'=>'587', 'user'=>'kedy211', 'password'=>'moxiu.com', 'debug'=>0, 'bufsize'=>1024);
# common config
use constant MD5SUM_FILE        => '/tmp/__monitor_md5sum_hash';
use constant APACHE_LOG_PATH    => '/usr/local/apache2/logs/access';
# apache
use constant APACHE_PORT        => 80;
use constant APACHE_SERVERS     => ('219.238.235.48', '219.238.235.47', '219.232.241.18', '219.232.241.19', '219.232.241.20', '219.232.241.21', '219.232.237.132');
# search
#use constant SEARCH_PORT        => 8000;
#use constant SEARCH_SERVERS     => ('search1.example.com');
use constant SERVERS     => (
			     '219.232.239.117:80',
			     '219.232.239.118:80', 
			     '219.232.239.119:80', 
			     '219.232.239.116:80', 
			     '219.232.239.114:80', 
			     '219.232.239.123:80', 
			     '219.232.239.121:3312',		#搜索 
			     '219.232.239.124:80', 
			     '219.232.239.125:22', 
			     '219.232.239.125:80', 
			     '219.232.239.126:80', 
			     '219.232.243.14:80', 
			     '219.232.243.14:3189', 
			     '219.232.243.54:80', 
			     '219.232.241.137:3189', 
			     '219.232.239.115:22', 
			     '219.232.239.120:22', 
			     '219.232.239.121:22', 
			     '219.232.239.123:22', 
			     '61.232.206.220:3189', 
			     '61.232.206.219:80', 
			     #'61.232.206.219:3389'
			     );


##############################
# Server port is alive check
##############################
sub check_server_alive {
	my($server, $port) = @_;

	$sock = IO::Socket::INET->new(PeerAddr=>$server, PeerPort=>$port, Proto=>'tcp', Timeout=>10);
	if (!$sock){
		return 0;
	}
	$sock->close();
	return 1;
}

##############################
# Check process is exist
##############################
sub check_process_exist {
	my $proc_name = shift;
	$line = `/bin/ps auxw | /bin/grep $proc_name | /bin/grep -v grep | /usr/bin/wc -l`;
	$line =~ s/^s+|s+$//g;
	if ($line == 0){
		return 0;
	}
	return 1;
}

##############################
# Check file md5 fingerprint
##############################
sub check_file_md5sum {
	my $io, $line;
	$filename = shift;
	@arr = split(/s/, `/usr/bin/md5sum $filename`);
	$filehash = shift(@arr);
	$io = IO::File->new();
	$io->open(MD5SUM_FILE, O_RDWR);
	if (!($line = $io->getLine())){
		$io->syswrite($filehash);
		$io->close;
		return true;
	}
	if ($line != $filehash){
		$io->truncate(0);
		$io->syswrite($filehash);
		$io->close;
		return true;
	}
	return true;
}

##############################
# Send notice sms
##############################
sub send_sms {
	my ($server, $error) = @_;
	my $sms_url = SMS_INFO;

	$url = $sms_url . '?h=' . $server . '&e=' . $error;
	$ret = get($url);
}

##############################
# Send notice mail
##############################
sub send_mail {
	my ($server, $port, $type) = @_;
	my %mailaddr = MAIL_ADDR;
	my %smtpinfo = SMTP_INFO;

# Count date time
	($sec, $min, $hour, $day, $mon, $year, $wday, $yday, $isdst) = localtime(time());
	$datetime = sprintf("%s-%s-%s %s:%s:%s", "20".substr($year,1,2), length($mon)==1?"0$mon":$mon, length($day)==1?"0$day":$day, length($hour)==1?"0$hour":$hour, length($min)==1?"0$min":$min, length($sec)==1?"0$sec":$sec);
	$subject .= "[$datetime]";
	$subject = 'ServerAlarm:  ' . $server . "  [$datetime]";

	$content = 'Datetime : ' . $datetime . "\n";
	$content .= 'IP地址 : ' . $server . "\n";
	$content .= 'Port : ' . $port . "\n";

	$status = '';
	if( $type == 'ping' ){
		$status = '无法ping 通 ' . $port . '端口';
	}

	$content .= 'Status : ' . $status. "\n";

	$smtp = Net::SMTP_auth->new($smtpinfo{'host'}, Debug => $smtpinfo{'debug'});

	$smtp->auth('LOGIN', $smtpinfo{'user'}, $smtpinfo{'password'}); #本行验证

	$smtp->mail($mailaddr{'from'});
	$smtp->to($mailaddr{'to'});
	$smtp->data();
	$smtp -> datasend( "Content-Type: text/plain; charset=utf-8\n" );
	$smtp -> datasend( "Content-Transfer-Encoding: base64\n" );
	$smtp -> datasend( "From: ".$mailaddr{'from'}."\n" );
	$smtp -> datasend( "To: ".$mailaddr{'to'}."\n" );
	$smtp->datasend("Subject: ".$subject."\n");
	$smtp->datasend("\n");
	$smtp->datasend(encode_base64($content, ''));
	$smtp->dataend();

	$smtp->quit;
}

##############################
# Check server alive main
##############################
sub monitor_main {
# check alive
	foreach $item (SERVERS) {
		my($server, $port) = split(':', $item);
		if(!check_server_alive($server, $port)){
			send_sms($item, 'ping');
			send_mail($server, $port, 'ping');
			sprintf('%s', $item);
		}
	}
}


##############################
# Main running
##############################

monitor_main();
